from sqlalchemy import Column, Integer, String, Boolean, Float, ForeignKey, desc, SmallInteger,orm
from werkzeug.security import generate_password_hash, check_password_hash

from app.libs.error_code import NotFount, AuthFailed
from app.models.base import Base, db


class User(Base):
    id = Column(Integer, primary_key=True)
    email = Column(String(24), unique=True, nullable=False)
    nickname = Column(String(24), unique=True)
    auth = Column(SmallInteger, default=1)  # 权限 1 普通用户 2 管理员
    # time=datetime.date(2018,5,20) #调用别的对象的复杂属性
    _password = Column('password', String(100))
    # 类变量是共有的，被一个对象使用hide删除掉后auth，别的对象使用时就找不到这个auth了
    # fields=['id', 'email', 'nickname', 'auth']
    '''由于sqlalchemy这种orm生成对象和普通对象不一样，使用的元类的方式，不会进入初始化，需要@orm.reconstructor'''
    @orm.reconstructor
    def __init__(self):
        self.fields = ['id', 'nickname', 'auth']

    @property
    def password(self):
        return self._password
    #密码加密
    @password.setter
    def password(self, raw):  # 处理密码，赋值给password（被@property装饰的方法）属性
        self._password = generate_password_hash(raw)

    @staticmethod
    def register_by_email(nickname, account, secret):
        with db.auto_commit():
            user = User()
            user.nickname = nickname
            user.email = account
            user.password = secret
            db.session.add(user)

    @staticmethod
    def verify(email, password):
        user = User.query.filter_by(email=email).first_or_404()
        if not user.check_password(password):
            raise AuthFailed()
        #scope 可以返回多个不同的权限
        scope = 'AdminScope' if user.auth == 2 else 'UserScope'
        return {'uid': user.id, 'scope':scope}
    #检验原始密码和加密密码
    def check_password(self, raw):
        if not self._password:
            return False
        return check_password_hash(self._password, raw)

    def delete(self):
        self.status = 0
